package com.shao.demo.feignconsumer.common.base;

import com.shao.demo.feignconsumer.common.BaseRuntimeException;
import com.shao.demo.feignconsumer.common.constans.StatusCode;
import com.shao.demo.feignconsumer.common.wapper.ResponseEntityWrapper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * @author zhiqi.shao
 * @Date 2018/5/24 9:00
 */
public class BaseController {
    private static final Logger log = LoggerFactory.getLogger(BaseController.class);

    public BaseController() {
    }

    @ExceptionHandler({RuntimeException.class, Exception.class, Error.class, Throwable.class})
    public ResponseEntityWrapper exceptionHandler(Exception e) {
        if (!(e instanceof BaseRuntimeException) && !(e instanceof BaseException)) {
            if (e instanceof MissingServletRequestParameterException) {
                log.info(e.getMessage(), e);
            } else {
                log.error(e.getMessage(), e);
            }
        } else {
            log.info(e.getMessage(), e);
        }

        if (e instanceof BaseRuntimeException) {
            return this.error(((BaseRuntimeException)e).getCode(), e.getMessage());
        } else {
            return e instanceof MissingServletRequestParameterException ? this.error(StatusCode.MISSING_REQUIRE_FIELD.getStatusCode(), e.getMessage()) : this.error(StatusCode.ERROR.getStatusCode(), e.getMessage());
        }
    }

    public ResponseEntityWrapper success() {
        return this.success((Object)null);
    }

    public <T> ResponseEntityWrapper success(T data) {
        return this.result(StatusCode.SUCCESS, data);
    }

    public ResponseEntityWrapper error() {
        return this.result(StatusCode.ERROR, (Object)null);
    }

    public ResponseEntityWrapper error(StatusCode statusCode) {
        return this.result(statusCode, (Object)null);
    }

    public ResponseEntityWrapper error(int code, String msg) {
        return this.result(code, msg, (Object)null);
    }

    private <T> ResponseEntityWrapper result(int code, String msg, T data) {
        return (new ResponseEntityWrapper.Builder()).statusCode(code).statusMessage(msg).data(data).build();
    }

    private <T> ResponseEntityWrapper result(StatusCode statusCode, T data) {
        return (new ResponseEntityWrapper.Builder()).with(statusCode, data).build();
    }
}

